#include "clientwindow.h"
#include "ui_clientwindow.h"
#include "taskqueue.h"
#include "clientoperation.h"
#include "clientthread.h"

#include <QDateTime>

ClientWindow::ClientWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::ClientWindow)
{
    ui->setupUi(this);
    ui->stackedTask->setCurrentWidget(ui->taskStart);

    // 将要管理的按钮放到按钮组中
    m_btnGroup.addButton(ui->consultBtn, 0);
    m_btnGroup.addButton(ui->verifyBtn, 1);
    m_btnGroup.addButton(ui->logoutBtn, 2);
    m_btnGroup.addButton(ui->setBtn, 3);

    // 设置按钮组中所有的按钮都有 checked 效果
    auto objs = m_btnGroup.buttons();
    for(int i=0; i<objs.size(); ++i)
    {
        objs.at(i)->setCheckable(true);
    }
    // 设置秘钥协商默认是被按下的状态
    ui->consultBtn->setChecked(true);
    m_prev = ui->consultBtn;    // 记录最初默认被选中的按钮
    m_index = 0;

    // 处理按钮组中按钮的点击事件
    void (QButtonGroup::*clicked)(int) = &QButtonGroup::buttonClicked;
    connect(&m_btnGroup, clicked, this, [=](int index)
    {
        ui->stackedTask->setCurrentWidget(ui->taskStart);
        m_index = index;    // 记录当前被选中的按钮的编号
        // 如果点击的按钮是设置按钮
        if(ui->setBtn == m_btnGroup.button(index))
        {
            // 切换到设置窗口
            ui->stackedWidget->setCurrentWidget(ui->set);
            ui->set->showPage(ConfigSet::Client);
        }
        else
        {
            // 切换到任务窗口
            ui->stackedWidget->setCurrentWidget(ui->task);
            // 初始化显示到任务按钮上的标题
            QStringList titles;
            titles << "开始秘钥协商" << "开始秘钥校验" << "开始秘钥注销";
            ui->startTask->setText(titles.at(index));
        }
        // 当按下了新的按钮, 之前被选中的按钮状态需要被更新
        // 取消之前按钮的选中状态, 当前按下的按钮设置为选中状态
        m_prev->setChecked(false);
        m_btnGroup.button(index)->setChecked(true);
        m_prev = m_btnGroup.button(index);
    });


    // 实例化客户端操作类对象
    m_cliOP = new ClientOperation;
    connect(m_cliOP,  &ClientOperation::showMsg, this, [=](QString log)
    {
        // 得到当前时间: 年月日 时分秒
        QDateTime tm = QDateTime::currentDateTime();
        // 格式化时间
        QString tmStr = tm.toString("yyyy-MM-dd hh:mm:ss");
        // 数据应该以追加的形式显示到窗口中
        ui->taskMsg->append(tmStr + ": " + log);
    });
}

ClientWindow::~ClientWindow()
{
    delete ui;
}

void ClientWindow::closeEvent(QCloseEvent *event)
{
    // 添加任务, 让子线程运行起来, 不被条件变量阻塞, 保证线程的顺利退出
    TaskQueue::getInstance()->addTask(ClientOperation::lastTask, NULL);
}

void ClientWindow::on_startTask_clicked()
{
    ui->stackedTask->setCurrentWidget(ui->infomation);
    ArgInfo *args = new ArgInfo;
    args->object = m_cliOP;
    // 添加任务到任务队列中
    switch(m_index)
    {
    case 0:
        // 秘钥协商
        args->prepare = ClientOperation::consultPrepare;
        args->dispose = ClientOperation::consultDispose;
        break;
    case 1:
        // 秘钥校验
        args->prepare = ClientOperation::verifyPrepare;
        args->dispose = ClientOperation::verifyDispose;
        break;
    case 2:
        // 秘钥注销
        args->prepare = ClientOperation::logoutPrepare;
        args->dispose = ClientOperation::logoutDispose;
        break;
    default:
        break;
    }
    // 得到任务队列的实例
    TaskQueue* taskQ = TaskQueue::getInstance();
    // 添加任务
    taskQ->addTask(ClientOperation::communication, args);
}
